<!DOCTYPE html>
<html>
<head>
	<!-- Global site tag (gtag.js) - Google Analytics -->
	<script async src="https://www.googletagmanager.com/gtag/js?id='UA-133422980-2"></script>
	<script>
	  window.dataLayer = window.dataLayer || [];
	  function gtag(){dataLayer.push(arguments);}
	  gtag('js', new Date());

	  gtag('config', 'UA-133422980-2');
	</script>

	<meta charset="utf-8">
	<meta http-equiv="x-ua-compatible" content="ie=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1">

	<title>
		gem5: Transition code blocks 
	</title>

	<!-- SITE FAVICON -->
	<link rel="shortcut icon" type="image/gif" href="/assets/img/gem5ColorVert.gif"/>

	<link rel="canonical" href="http://localhost:4000/documentation/learning_gem5/part3/cache-transitions/">
	<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,700,800,600' rel='stylesheet' type='text/css'>
	<link href='https://fonts.googleapis.com/css?family=Muli:400,300' rel='stylesheet' type='text/css'>

	<!-- FAVICON -->
	<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

	<!-- BOOTSTRAP -->
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

	<!-- CUSTOM CSS -->
	<link rel="stylesheet" href="/css/main.css">
</head>


<body>
	<nav class="navbar navbar-expand-md navbar-light bg-light">
  <a class="navbar-brand" href="/">
		<img src="/assets/img/gem5ColorLong.gif" alt="gem5" height=55px>
	</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarNavDropdown">
    <!-- LIST FOR NAVBAR -->
    <ul class="navbar-nav ml-auto">
      <!-- HOME -->
      <li class="nav-item ">
        <a class="nav-link" href="/">Home</a>
      </li>

      <!-- ABOUT -->
			<li class="nav-item dropdown ">
				<a class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
					About
				</a>
				<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
          <a class="dropdown-item" href="/about">About gem5</a>
          <a class="dropdown-item" href="/publications">Publications</a>
          <a class="dropdown-item" href="/governance">Governance</a>
				</div>
			</li>

      <!-- DOCUMENTATION -->
			<li class="nav-item dropdown active">
				<a class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
					Documentation
				</a>
				<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
					<!-- Pull navigation from _data/documentation.yml -->
					
            <a class="dropdown-item" href="/documentation">gem5 documentation</a>
					
            <a class="dropdown-item" href="/documentation/learning_gem5/introduction">Learning gem5</a>
					
            <a class="dropdown-item" href="http://doxygen.gem5.org/release/current/index.html">gem5 Doxygen</a>
					
            <a class="dropdown-item" href="/documentation/reporting_problems">Reporting Problems</a>
					
				</div>
			</li>

      <!-- EVENTS -->
			<li class="nav-item dropdown ">
        <a class="nav-link" href="/events/">Events</a>
			</li>

      <!-- CONTRIBUTING -->
      <li class="nav-item ">
        <a class="nav-link" href="/contributing">Contributing</a>
      </li>

      <!-- BLOG -->
      <li class="nav-item ">
        <a class="nav-link" href="/blog">Blog</a>
      </li>

      <!-- SEARCH -->
			<li class="nav-item ">
        <a class="nav-link" href="/search">Search</a>
      </li>
    </ul>
  </div>
</nav>

	<main>
		<div class="sidenav-top">
  <div class="sidenav-brand bg-light">
    <a href="/"><img src="/assets/img/gem5ColorLong.gif" height="55px"></a>
  </div>
  <div class="search">
    <form action="/search" method="get">
      <!-- <label for="search-box"><i class="fa fa-search"></i></label> -->
      <input type="text" name="query">
      <button type="submit" name="submit"><i class="fa fa-search"></i></button>
    </form>
  </div>
</div>
<div class="sidenav">
  <!-- Pull navigation from _data/documentation.yml -->
  
    
  
    
    
      <a class="item" href="/documentation/learning_gem5/introduction" role="button" aria-expanded="false" aria-controls="collapseExample">
        Introduction
      </a>
      <div class="collapse " id="introduction">
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#part1" role="button" aria-expanded="false" aria-controls="collapseExample">
        Getting Started
      </a>
      <div class="collapse " id="part1">
        
          <a class="subitem " href="/documentation/learning_gem5/part1/building">Building gem5</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part1/simple_config">Creating a simple configuration script</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part1/cache_config">Adding cache to configuration script</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part1/gem5_stats">Understanding gem5 statistics and output</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part1/example_configs">Using the default configuration scripts</a>
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#part2" role="button" aria-expanded="false" aria-controls="collapseExample">
        Modifying/Extending
      </a>
      <div class="collapse " id="part2">
        
          <a class="subitem " href="/documentation/learning_gem5/part2/environment">Setting up your development environment</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/helloobject">Creating a very simple SimObject</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/debugging">Debugging gem5</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/events">Event-driven programming</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/parameters">Adding parameters to SimObjects and more events</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/memoryobject">Creating SimObjects in the memory system</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/simplecache">Creating a simple cache object</a>
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#part3" role="button" aria-expanded="false" aria-controls="collapseExample">
        Modeling Cache Coherence with Ruby
      </a>
      <div class="collapse show" id="part3">
        
          <a class="subitem " href="/documentation/learning_gem5/part3/MSIintro">Introduction to Ruby</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/cache-intro">MSI example cache protocol</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/cache-declarations">Declaring a state machine</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/cache-in-ports">In port code blocks</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/cache-actions">Action code blocks</a>
        
          <a class="subitem active" href="/documentation/learning_gem5/part3/cache-transitions">Transition code blocks</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/directory">MSI Directory implementation</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/MSIbuilding">Compiling a SLICC protocol</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/configuration">Configuring a simple Ruby system</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/running">Running the simple Ruby system</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/MSIdebugging">Debugging SLICC Protocols</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/simple-MI_example">Configuring for a standard protocol</a>
        
      </div>
    
      <a class="item" href="/documentation/learning_gem5/gem5_101/" role="button" aria-expanded="false" aria-controls="collapseExample">
        gem5 101
      </a>
      <div class="collapse " id="gem5_101">
        
      </div>
    
    
  
    
  
    
  
</div>


<div class="container" id="doc-container">
  <div class="edit"><a href="https://gem5.googlesource.com/public/gem5-website/+/refs/heads/master/README.md">Edit this page</a></div>
  <b>authors:</b> Jason Lowe-Power<br>
  

  <br>
  <h1 id="transition-code-blocks">Transition code blocks</h1>

<p>Finally, we’ve reached the final section of the state machine file! This
section contains the details for all of the transitions between states
and what actions to execute during the transition.</p>

<p>So far in this chapter we have written the state machine top to bottom
one section at a time. However, in most cache coherence implementations
you will find that you need to move around between sections. For
instance, when writing the transitions you will realize you forgot to
add an action, or you notice that you actually need another transient
state to implement the protocol. This is the normal way to write
protocols, but for simplicity this chapter goes through the file top to
bottom.</p>

<p>Transition blocks consist of two parts. First, the first line of a
transition block contains the begin state, event to transition on, and
end state (the end state may not be required, as we will discuss below).
Second, the transition block contains all of the actions to execute on
this transition. For instance, a simple transition in the MSI protocol
is transitioning out of Invalid on a Load.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">transition</span><span class="p">(</span><span class="n">I</span><span class="p">,</span> <span class="n">Load</span><span class="p">,</span> <span class="n">IS_D</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">allocateCacheBlock</span><span class="p">;</span>
    <span class="n">allocateTBE</span><span class="p">;</span>
    <span class="n">sendGetS</span><span class="p">;</span>
    <span class="n">popMandatoryQueue</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>First, you specify the transition as the “parameters” to the
<code class="highlighter-rouge">transition</code> statement. In this case, if the initial state is <code class="highlighter-rouge">I</code> and
the event is <code class="highlighter-rouge">Load</code> then transition to <code class="highlighter-rouge">IS_D</code> (was invalid, going to
shared, waiting for data). This transition is straight out of Table 8.3
in Sorin et al.</p>

<p>Then, inside the <code class="highlighter-rouge">transition</code> code block, all of the actions that will
execute are listed in order. For this transition first we allocate the
cache block. Remember that in the <code class="highlighter-rouge">allocateCacheBlock</code> action the newly
allocated entry is set to the entry that will be used in the rest of the
actions. After allocating the cache block, we also allocate a TBE. This
could be used if we need to wait for acks from other caches. Next, we
send a GetS request to the directory, and finally we pop the head entry
off of the mandatory queue since we have fully handled it.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">transition</span><span class="p">(</span><span class="n">IS_D</span><span class="p">,</span> <span class="p">{</span><span class="n">Load</span><span class="p">,</span> <span class="n">Store</span><span class="p">,</span> <span class="n">Replacement</span><span class="p">,</span> <span class="n">Inv</span><span class="p">})</span> <span class="p">{</span>
    <span class="n">stall</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>In this transition, we use slightly different syntax. According to Table
8.3 from Sorin et al., we should stall if the cache is in IS_D on
loads, stores, replacements, and invalidates. We can specify a single
transition statement for this by including multiple events in curly
brackets as above. Additionally, the final state isn’t required. If the
final state isn’t specified, then the transition is executed and the
state is not updated (i.e., the block stays in its beginning state). You
can read the above transition as “If the cache block is in state IS_D
and there is a load, store, replacement, or invalidate stall the
protocol and do not transition out of the state.” You can also use curly
brackets for beginning states, as shown in some of the transitions
below.</p>

<p>Below is the rest of the transitions needed to implement the L1 cache
from the MSI protocol.</p>

<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">transition</span><span class="p">(</span><span class="n">IS_D</span><span class="p">,</span> <span class="p">{</span><span class="n">DataDirNoAcks</span><span class="p">,</span> <span class="n">DataOwner</span><span class="p">},</span> <span class="n">S</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">writeDataToCache</span><span class="p">;</span>
    <span class="n">deallocateTBE</span><span class="p">;</span>
    <span class="n">externalLoadHit</span><span class="p">;</span>
    <span class="n">popResponseQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">({</span><span class="n">IM_AD</span><span class="p">,</span> <span class="n">IM_A</span><span class="p">},</span> <span class="p">{</span><span class="n">Load</span><span class="p">,</span> <span class="n">Store</span><span class="p">,</span> <span class="n">Replacement</span><span class="p">,</span> <span class="n">FwdGetS</span><span class="p">,</span> <span class="n">FwdGetM</span><span class="p">})</span> <span class="p">{</span>
    <span class="n">stall</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">({</span><span class="n">IM_AD</span><span class="p">,</span> <span class="n">SM_AD</span><span class="p">},</span> <span class="p">{</span><span class="n">DataDirNoAcks</span><span class="p">,</span> <span class="n">DataOwner</span><span class="p">},</span> <span class="n">M</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">writeDataToCache</span><span class="p">;</span>
    <span class="n">deallocateTBE</span><span class="p">;</span>
    <span class="n">externalStoreHit</span><span class="p">;</span>
    <span class="n">popResponseQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">(</span><span class="n">IM_AD</span><span class="p">,</span> <span class="n">DataDirAcks</span><span class="p">,</span> <span class="n">IM_A</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">writeDataToCache</span><span class="p">;</span>
    <span class="n">storeAcks</span><span class="p">;</span>
    <span class="n">popResponseQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">({</span><span class="n">IM_AD</span><span class="p">,</span> <span class="n">IM_A</span><span class="p">,</span> <span class="n">SM_AD</span><span class="p">,</span> <span class="n">SM_A</span><span class="p">},</span> <span class="n">InvAck</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">decrAcks</span><span class="p">;</span>
    <span class="n">popResponseQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">({</span><span class="n">IM_A</span><span class="p">,</span> <span class="n">SM_A</span><span class="p">},</span> <span class="n">LastInvAck</span><span class="p">,</span> <span class="n">M</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">deallocateTBE</span><span class="p">;</span>
    <span class="n">externalStoreHit</span><span class="p">;</span>
    <span class="n">popResponseQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">({</span><span class="n">S</span><span class="p">,</span> <span class="n">SM_AD</span><span class="p">,</span> <span class="n">SM_A</span><span class="p">,</span> <span class="n">M</span><span class="p">},</span> <span class="n">Load</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">loadHit</span><span class="p">;</span>
    <span class="n">popMandatoryQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">(</span><span class="n">S</span><span class="p">,</span> <span class="n">Store</span><span class="p">,</span> <span class="n">SM_AD</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">allocateTBE</span><span class="p">;</span>
    <span class="n">sendGetM</span><span class="p">;</span>
    <span class="n">popMandatoryQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">(</span><span class="n">S</span><span class="p">,</span> <span class="n">Replacement</span><span class="p">,</span> <span class="n">SI_A</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sendPutS</span><span class="p">;</span>
    <span class="n">forwardEviction</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">(</span><span class="n">S</span><span class="p">,</span> <span class="n">Inv</span><span class="p">,</span> <span class="n">I</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sendInvAcktoReq</span><span class="p">;</span>
    <span class="n">deallocateCacheBlock</span><span class="p">;</span>
    <span class="n">forwardEviction</span><span class="p">;</span>
    <span class="n">popForwardQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">({</span><span class="n">SM_AD</span><span class="p">,</span> <span class="n">SM_A</span><span class="p">},</span> <span class="p">{</span><span class="n">Store</span><span class="p">,</span> <span class="n">Replacement</span><span class="p">,</span> <span class="n">FwdGetS</span><span class="p">,</span> <span class="n">FwdGetM</span><span class="p">})</span> <span class="p">{</span>
    <span class="n">stall</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">(</span><span class="n">SM_AD</span><span class="p">,</span> <span class="n">Inv</span><span class="p">,</span> <span class="n">IM_AD</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sendInvAcktoReq</span><span class="p">;</span>
    <span class="n">forwardEviction</span><span class="p">;</span>
    <span class="n">popForwardQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">(</span><span class="n">SM_AD</span><span class="p">,</span> <span class="n">DataDirAcks</span><span class="p">,</span> <span class="n">SM_A</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">writeDataToCache</span><span class="p">;</span>
    <span class="n">storeAcks</span><span class="p">;</span>
    <span class="n">popResponseQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">(</span><span class="n">M</span><span class="p">,</span> <span class="n">Store</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">storeHit</span><span class="p">;</span>
    <span class="n">popMandatoryQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">(</span><span class="n">M</span><span class="p">,</span> <span class="n">Replacement</span><span class="p">,</span> <span class="n">MI_A</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sendPutM</span><span class="p">;</span>
    <span class="n">forwardEviction</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">(</span><span class="n">M</span><span class="p">,</span> <span class="n">FwdGetS</span><span class="p">,</span> <span class="n">S</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sendCacheDataToReq</span><span class="p">;</span>
    <span class="n">sendCacheDataToDir</span><span class="p">;</span>
    <span class="n">popForwardQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">(</span><span class="n">M</span><span class="p">,</span> <span class="n">FwdGetM</span><span class="p">,</span> <span class="n">I</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sendCacheDataToReq</span><span class="p">;</span>
    <span class="n">deallocateCacheBlock</span><span class="p">;</span>
    <span class="n">popForwardQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">({</span><span class="n">MI_A</span><span class="p">,</span> <span class="n">SI_A</span><span class="p">,</span> <span class="n">II_A</span><span class="p">},</span> <span class="p">{</span><span class="n">Load</span><span class="p">,</span> <span class="n">Store</span><span class="p">,</span> <span class="n">Replacement</span><span class="p">})</span> <span class="p">{</span>
    <span class="n">stall</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">(</span><span class="n">MI_A</span><span class="p">,</span> <span class="n">FwdGetS</span><span class="p">,</span> <span class="n">SI_A</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sendCacheDataToReq</span><span class="p">;</span>
    <span class="n">sendCacheDataToDir</span><span class="p">;</span>
    <span class="n">popForwardQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">(</span><span class="n">MI_A</span><span class="p">,</span> <span class="n">FwdGetM</span><span class="p">,</span> <span class="n">II_A</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sendCacheDataToReq</span><span class="p">;</span>
    <span class="n">popForwardQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">({</span><span class="n">MI_A</span><span class="p">,</span> <span class="n">SI_A</span><span class="p">,</span> <span class="n">II_A</span><span class="p">},</span> <span class="n">PutAck</span><span class="p">,</span> <span class="n">I</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">deallocateCacheBlock</span><span class="p">;</span>
    <span class="n">popForwardQueue</span><span class="p">;</span>
<span class="p">}</span>

<span class="n">transition</span><span class="p">(</span><span class="n">SI_A</span><span class="p">,</span> <span class="n">Inv</span><span class="p">,</span> <span class="n">II_A</span><span class="p">)</span> <span class="p">{</span>
    <span class="n">sendInvAcktoReq</span><span class="p">;</span>
    <span class="n">popForwardQueue</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>You can download the complete <code class="highlighter-rouge">MSI-cache.sm</code> file
<a href="/_pages/static/scripts/part3/MSI_protocol/MSI-cache.sm">here</a>.</p>

  <br>

  <!-- RETRIVE PREVIOUS PAGE LINK -->
  
    
  
    
  
    
  
    
  

  <!-- RETRIEVE NEXT PAGE LINK -->
  
    
  
    
  
    
  
    
  


  <div class="navbuttons">
    
      <a href=""><button type="button" class="btn btn-outline-primary">PREVIOUS</button></a>
    

    
      <a href=""><button type="button" class="btn btn-outline-primary">NEXT</button></a>
    
  </div>
</div>

	</main>
	<footer class="page-footer">
	<div class="container">
		<div class="row">

			<div class="col-12 col-sm-4">
				<p>gem5</p>
				<p><a href="/about">About</a></p>
				<p><a href="/publications">Publications</a></p>
				<p><a href="/contributing">Contributing</a></p>
				<p><a href="/governance">Governance</a></p>
			<br></div>

			<div class="col-12 col-sm-4">
				<p>Docs</p>
				<p><a href="/documentation">Documentation</a></p>
				<p><a href="http://gem5.org/Documentation">Old Documentation</a></p>
				<p><a href="https://gem5.googlesource.com/public/gem5">Source</a></p>
			<br></div>

			<div class="col-12 col-sm-4">
				<p>Help</p>
				<p><a href="/search">Search</a></p>
				<p><a href="/mailing_lists">Mailing Lists</a></p>
				<p><a href="https://gem5.googlesource.com/public/gem5-website/+/refs/heads/master/README.md">Website Source</a></p>
			<br></div>

		</div>
	</div>
</footer>


	<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
	<script src="https://unpkg.com/commentbox.io/dist/commentBox.min.js"></script>

	<script>
	  // When the user scrolls down 20px from the top of the document, show the button
	  window.onscroll = function() {scrollFunction()};

	  function scrollFunction() {
	      if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 20) {
	          document.getElementById("myBtn").style.display = "block";
	      } else {
	          document.getElementById("myBtn").style.display = "none";
	      }
	  }

	  // When the user clicks on the button, scroll to the top of the document
	  function topFunction() {
	      document.body.scrollTop = 0;
	      document.documentElement.scrollTop = 0;
	  }

		import commentBox from 'commentbox.io';
		// or
		const commentBox = require('commentbox.io');
		// or if using the CDN, it will be available as a global "commentBox" variable.

		commentBox('my-project-id');

	</script>

</body>


</html>
